/**
 * Copyright (c) 2012 Nokia Corporation. 
 */

package com.nokia.example.simplepurchase.uicomponents;

import javax.microedition.lcdui.Font;

/**
 * Utility class for word wrapping with Graphics.drawString().
 */
public class TextWrapper {
	// Constants
	private char LINE_BREAK = '\n';
	private char WHITE_SPACE = ' ';
	
	// Members
	private String _text = null;
	private final Font _font;
	private final int _fontHeight;
	private int _totalLength = 0;
	private int _width = 0;
	private int _start = 0;
	private int _position = 0;
	
	/**
	 * Constructor.
	 */
	public TextWrapper(Font font, int width) {
		if (font == null || width <= 0) {
			throw new IllegalArgumentException();
		}
		
		_font = font;
		_fontHeight = _font.getHeight();
		_width = width;
	}
	
	/**
	 * 
	 * @param text
	 * @param font
	 */
	public void setText(String text) {
		if (text == null) {
			throw new IllegalArgumentException();
		}
		
		_text = text;
		_totalLength = _text.length();
		_start = 0;
		_position = 0;
	}
	
	/**
	 * 
	 * @return
	 */
	public String text() {
		return _text;
	}
	
	/**
	 * 
	 * @return
	 */
	public int lineHeight() {
		return _fontHeight;
	}
	
	/**
	 * 
	 * @return
	 */
	public boolean hasMoreLines() {
	    return (_position < (_totalLength - 1));
	}
	
	public String nextLine() {
		int next = nextPosition();
	     
	    if (_start >= _totalLength || next > _totalLength) {
	    	return null;
	    }
	     
	    String retval = _text.substring(_start, next);
	    _start = next;
	     
	    if ((_totalLength - 1 > _start) &&
	    		((_text.charAt(_start) == LINE_BREAK) ||
	    		 (_text.charAt(_start) == WHITE_SPACE)))
	    {
	    	_position++;
	        _start++;
	    }
	    
	    //System.out.println("TextWrapper::nextLine(): \"" + retval.trim() + "\"");
	    return retval.trim();
	}

	/**
	 * 
	 * @return
	 */
	private int nextPosition() {
		int i = nextWordIndex(_position);
	    int lastBreak = -1;
	    String line = _text.substring(_position, i);
	    int lineWidth = _font.stringWidth(line);
	     
	    while (i < _totalLength && lineWidth <= _width) {
	    	if (_text.charAt(i) == WHITE_SPACE) {
	    		lastBreak = i;
	        } 
	        else if (_text.charAt(i) == LINE_BREAK) {
	        	lastBreak = i;
	            break;
	        }
	    	
	        if (++i < _totalLength) {
	            i = nextWordIndex(i);
	            line = _text.substring(_position, i);
	            lineWidth = _font.stringWidth(line);
	        }
	    }
	    
	    if (i == _totalLength && lineWidth <= _width) {
	    	_position = i;
	    }
	    else if (lastBreak == _position) {
	    	_position++;
	    }
	    else if (lastBreak < _position) {
	    	_position = i;
	    }
	    else {
	    	_position = lastBreak;
	    }
	    
	    return _position;
	}
	
	/**
	 * 
	 * @param startIndex
	 * @return
	 */
	private int nextWordIndex(int startIndex) {
		int space = _text.indexOf(WHITE_SPACE, startIndex);
	    int newLine = _text.indexOf(LINE_BREAK, startIndex);
	    
	    if (space == -1) { 
	    	space = _totalLength;
	    }
	    
	    if (newLine == -1) {
	    	newLine = _totalLength;
	    }
	    
	    if (space < newLine) {
	    	return space;
	    }
	    
	    return newLine;
	}
}
